package com.cskaoyan.javase.oop2._1extends._7initialization._5exercise;
/**
 * 总结一下到目前为止，创建对象过程中可能碰到的结构的执行顺序（最全）：
 *
 * 我们将程序的运行分成两部分：
 *
 * 第一部分：类加载
 *
 * 首先程序要从main方法启动，这意味着首先要触发，装有main方法的那个类的类加载。
 *
 * 类加载过程中，一定要考虑连环触发类加载的情况：
 *
 * 类中有静态成员变量创建对象，那么一定会触发其它类的类加载。
 * 该类还有父类，于是触发父类类加载。
 * 类加载这个过程中，静态代码块的代码一定会执行，不要忘记了。
 * 如果有静态成员变量的显式赋值，那么显式赋值和静态代码块，按照代码的书写顺序从上往下执行。
 * 类加载整个程序运行期间只有一次，如有通过继承连环触发类加载，那么顺序是先父后子，从最顶层父类开始。
 *
 *  第二部分：创建对象
 *
 * 切记类加载是懒加载，有些类可能等到main方法执行到一半才触发类加载。
 *
 * 这个就要随机应变了，以下步骤，都默认类加载全部结束了。
 * new对象时，首先去找到new对象的构造器，然后观察第一行
 *
 * 如果它的首行显式地调用了另一个构造器（可能是this(参数)，也可能是super(参数)）
 *
 * 那么程序会先跳转到那个构造器，再去看代码首行有没有显式调用另一个构造器
 *
 * 直到找到一个构造器它隐含的super()指向Object类的无参构造
 * 于是开始按照这个类中构造代码块和显式赋值的代码书写顺序，从上到下执行其中的代码
 * 最后执行这个类的构造器
 * 开始执行被跳转的构造器，同样先执行显式赋值和构造代码块后执行构造器
 * 最后执行完new对象构造器，创建对象过程结束。
 * 如果它的首行没有显式调用另一个构造器，那么必定隐含super()指向父类的无参构造器。
 *
 * 如果直接指向Object类的无参构造，那十分简单，直接不用管
 *
 * 执行类中的显式赋值和构造代码块，最后执行构造器
 * 如果指向一个普通父类的无参构造，那就观察首行，根据情况执行步骤a或b
 * 最终一定父类构造器执行完毕，回到new对象的类中，执行完毕new对象构造器，创建对象过程结束。
 *
 * @since 10:50
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        PrimaryStudent primaryStudent = new PrimaryStudent(666,888,"hello");
        System.out.println(primaryStudent.psVar);
    }
}
class Person {
    static {
        System.out.println("Person类加载");
    }
    {
        System.out.println("Person构造代码块");
    }
    public Person() {
        // super();
        System.out.println("Person类的无参构造");
    }
}
class Student extends Person {
    static {
        System.out.println("Student类加载");
    }
    {
        System.out.println("Student构造代码块");
    }
    int sVar;
    String sVarString;
    public Student() {
        System.out.println("Student类无参构造");
    }
    public Student(int sVar) {
        // 这里什么都没有,所以隐含super(); 指向父类的无参构造去
        System.out.println("Student int构造方法");
        this.sVar = sVar;
    }
    public Student(int sVar, String sVarString) {
        this(sVar);
        System.out.println("Student int String构造方法");
        this.sVarString = sVarString;
    }
}
class PrimaryStudent extends Student {
    static {
        System.out.println("PrimaryStudent类加载");
    }
    {
        System.out.println("PrimaryStudent构造代码块");
    }
    int psVar = 10;
    public PrimaryStudent(int psVar, int sVar, String sVarString) {
        super(sVar, sVarString);
        System.out.println("PrimaryStudent类的 三参构造");
        this.psVar = psVar = 100;
    }
}